// let list: Array<number | string | (() => []) > = [1, 2, 3, "1", function(){
//     return []
// }];
// 枚举 后端项目中 用于  接口的 messsage 的错误信息保存和 code状态码
enum Direction {
    ERROR = 404,
    SystemError = 500,
    SUCCESSS = 200
}

enum ErrorMessage {
    NODATA = "没有数据",
    SystemErrorMessage = "系统程序出现错误，请稍后再试",
    OK = "请求成功"
}

// let a: any  = 345
// console.log(Direction.SystemError);
// a = []
// a = ""
// a = 1


// interface responseBase<U> {
//     readonly code: number;
//     readonly data: U;
//     readonly message: string;
//     getName(): string
// }
// interface item {
//     id: number;
//     name: string;
// }

// interface item2 extends item {
//     age: string
// }

// function getIndexData(): responseBase<Array<item>> {
//     return undefined;
// }

// function getIndexDataDDD(): responseBase<item2> {
//     return undefined;
// }

// let obj: objType = {
//     id: 1,
//     name: "222",
//     test: []
// }

// console.log(obj.id);


// Any 
// | 联合类型
// & 交叉类型   合并两个类型为一个类型
// 自定义的类型
// 类型别名
// instanceof 一个类是否是另一个类的子类呢


//  类型断言  <string>a
// !  变量初始数值可以为空

// 接口 interface: 代码开发的规范标准(就是约束各种东西的数据类型的)
//   readonly
//   ? 表示对象属性可选 { id: string, name?: string }
//   函数类型：(source: string, subString: string): boolean;
//   可索引类型
//    数组: [index: number]: any;  [1]
//    对象: [key: string]: any; { id: 1 }
//   类实现接口，实现对类的代码约束 
//   接口实现继承，复用接口
//   接口继承类（一般不用）

// 类，修饰符
//   public 方法和变量默认就是
//   private 只有当前类中可以访问，子类和类实例都不能访问
//   protected 子类可以访问，类实例不行
//   readonly 写在类的属性上
//   constructor(readonly name: string = "") {}
//   static  保存在类身上，类型.静态属性（方法）
//   构造函数类型  {new(...args: string[]): T; }   { new (...args: string[]): void }
//     new (...args: string[]) => T

//  接口 和 抽象类 有什么差别？有什么相同的地方？
//  抽象类:  既有接口约束类的特性，又可以实现方法的细节，被子类基础使用
//  类的类型： typeof 类名

//  函数 
//   可选参数 加 ?，注意要在最后
//   剩余参数 ...args: string[]

//  泛型
   

//  interface 和 type 区别
//  类型别名和接口一样，可以使用泛型
//    type不能被 extends 和 implements
//    interface 可以声明合并，而type则不允许
// function a(): string {
//     return "111"
// } 
// 字符串字面量类型
// 数字字面量类型
//  type Easing = "ease-in" | "ease-out" | "ease-in-out";
//  easing: Easing
// 索引类型
//  keyof 取key来判断
// 映射类型  in
//  type Partial<T> = {
//    [P in keyof T]: T[P];
//  }

// 预定义的有条件类型
// TypeScript 2.8在lib.d.ts里增加了一些预定义的有条件类型：

// Exclude<T, U> -- 从T中剔除可以赋值给U的类型。 我两没有的（以T为准）
// Extract<T, U> -- 提取T中可以赋值给U的类型。  我两都有的
// NonNullable<T> -- 从T中剔除null和undefined。
// ReturnType<T> -- 获取函数返回值类型。
// InstanceType<T> -- 获取构造函数类型的实例类型。



// let res: string = a()


// let someValue: any = "this is a string";
// console.log( (<string>someValue).length );
// console.log( (someValue as string).length );


// interface test {
//     color?: string;
// }

// var eee: test = { dd: '' }
// interface f {
//     (name: string): void
// }

// let a: f = function (name: string) {
    
// }


// interface BaseType {
//     name: string;
//     getMyName(name: string): number;
// }

// class My implements BaseType {
//     name = "1"
   
//     getMyName(name: string): number {
//         throw new Error("Method not implemented.");
//     }
   
//     constructor(one: string, two: string) {
//     }
// }


// function pluck<T, K extends keyof T>(o: T, names: K[]):  T[K][] {
//     return names.map(n => o[n]);
//     // person.test  number
//   }
  
//   interface Person {
//       name: string;
//       age: number;
//       test: number;
//   }
//   let person: Person = {
//       name: 'Jarid',
//       age: 35,
//       test: 1
//   };


//   let strings: string[] = pluck(person, ['name']); // ok, string[]


// interface Person {
//     name: string;
//     age: number;
// }


// // [key: string]: any;
// type Picks<T, K extends keyof T> = {
//     [P in K]: T[P]; //Person.name
// }

// type ThreeStringProps = Picks<Person,"name">
// var a: ThreeStringProps = {
//     name: '111'
// };

// let ddd: string = "1"
// console.log(typeof String == typeof ddd);

